import React, { useMemo, useContext } from 'react';
import { Checkbox, Empty, Spin,message } from 'antd';
import { getMessage } from '@inbiz/react';
import { GlobalRegistry } from '@inbiz/core';
import { getFileTypeIconSvg, InbizIcon } from '@inbiz/utils';
import EventContext from '../../common/EventContext';
import type { ReactElement } from 'react';
import type { IConfigItem } from './content';
import type useTemplate from '../../common/useTemplate';
import type { ISearchData } from '../../../designer/service';

function ContentItem({
  config,
  checked,
  onSelect,
  data,
  view,
  showStyle,
  params,
  $params,
  dataList
}: {
  checked?: boolean;
  onSelect?: (node: ISearchData['RawList'][number], checked: boolean) => void;
  config: IConfigItem['config'];
  data: ISearchData['RawList'][number];
  view: IView;
  showStyle: IConfigItem['config']['showStyle'];
  params: any,
  $params: any,
  dataList: any,
}) {

  const { configEvents, emit, inbiz } = useContext(EventContext);
  const setHighLightWord = (replacedstring: string | undefined, isInReasultSearch?: boolean) => {
    let lightWord = ''
    if (replacedstring) {
      lightWord = String(replacedstring).replaceAll(params.KeyWord, `<span style="color: var(--search-color)">${params.KeyWord}</span>`)
      if (isInReasultSearch) {
        lightWord = String(replacedstring)
      }
      if (params.SecondaryWord) {
        const secondaryWords = params.SecondaryWord.split(',')
        for (let index = 0; index < secondaryWords.length; index++) {
          const element = secondaryWords[index];
          lightWord = lightWord.replaceAll(element, `<span style="color: var(--search-color)">${element}</span>`)
        }
      }
    }
    return lightWord
  }
  //处理最后一特定字符串
  const lastStr = (str, val, isSuffix) => {
    return str.lastIndexOf(val) > -1 ? (isSuffix ? str.substring(str.lastIndexOf(val), str.length) : str.substring(0, str.lastIndexOf(val))) : str
  }
  function getLocalStorageWithExpiry(key) {
    if (!localStorage.getItem(key)) return null;
    const item = JSON.parse(localStorage.getItem(key) || '');
    if (!item) {
      return null;
    }
    const now = new Date();
    if (item.expiry && now.getTime() > item.expiry) {
      localStorage.removeItem(key);
      return null;
    }
    return item.value;
  };
  function setLocalStorageWithExpiry(key, value, expiry?) {
    const now = new Date();
    const item = {
      value: value,
      expiry: expiry ? now.getTime() + expiry : null
    };
    localStorage.setItem(key, JSON.stringify(item));
  };

  const setLocalPreviewData = (id, list, name, fileGuid) => {
    let previewFilesData = getLocalStorageWithExpiry('previewFilesData') || []
    if (previewFilesData.length) {
      previewFilesData = previewFilesData.filter((item) => item.id != id)
    }
    setLocalStorageWithExpiry('previewFilesData', [...previewFilesData, {
      id: id,
      fileGuid,
      fileds: list.filter((item) => item.filetype != 1).map((item) => item.fileid),
      fileSuffix: lastStr(name, '.', true),
    }])
  }
  const previewFile = () => {
    if (data.RawData?.permission == 0) {
      return message.warn(getMessage('SearchResultEnginePreview.noPermissionAccess'))
    }
    if (data.RawData.permission) {
      if (data.RawData?.fileid) {
        setLocalPreviewData(data.RawData?.fileid, dataList, data.RawData?.filename, data.RawData?.fileguid)
        const previewUrl = `${window.ecmPlugins?.config?.previewURL || '/preview.html'}?fileid=${data.RawData?.fileguid}&moduleId=search&uid=${window.btoa(inbiz.userInfo?.id)}&displayControl=32768&t=${new Date().getTime()}`
        window.open(previewUrl, '_blank')
      }
    }
  }
  const previewFolder = () => {
    if (data.RawData?.permission == 0) {
      return message.warn(getMessage('SearchResultEnginePreview.noPermissionAccess'))
    }
    if (data.RawData?.folderid) {
      let previewUrl = ''
      if (data.RawData?.folderpath.startsWith('1')) {
        previewUrl = `/index.html#doc/enterprise/${data.RawData?.folderid}`
      } else if (data.RawData?.folderpath.startsWith('7')) {
        previewUrl = `/index.html#doc/team/${data.RawData?.folderid}`
      } else {
        previewUrl = `/index.html#doc/person/${data.RawData?.folderid}`
      }
      window.open(previewUrl, '_blank')
    }
  }
  const setTag = (tag: string) => {
    const SearchWhere = tag ? `(filetag:(*${tag}*) OR filetag_suggest:(*${tag}*))` : tag
    $params({
      ...params,
      SearchWhere,
    })
  }
  return useMemo(() => {
    // 复选框
    const $checkbox = config.checkbox && (
      <Checkbox
        className="itemCheckbox"
        checked={checked}
        onChange={(e) => onSelect?.(data, e.target.checked)}
      />
    );
    let htmlStr: string;
    const iconUri = getFileTypeIconSvg(
      config.IndexName == 'folder' ? '.folder' : data.RawData?.filename,
    ) as string;

    if (showStyle === 'list') {
      htmlStr =
        configEvents.current?.onRenderItem?.({
          data,
          columnField: config.columnField,
          type: 'list',
          IndexName: config.IndexName,
          checked,
          config,
          setTag,
          dataList
        }) ||
        config.columnField
          ?.map((filed) => {
            return `<p class="${filed.IndexFieldName == 'filename' || filed.IndexFieldName == 'foldername' ? 'itemTitle' : ''}">
                        ${filed.IndexFieldDesc || filed.IndexFieldName}: <span class="${filed.IndexFieldName == 'filename' || filed.IndexFieldName == 'foldername' ? 'itemTitle' : ''}">
                        ${setHighLightWord(data.HighlightList?.[filed.IndexFieldName], true) ||setHighLightWord(data.RawData?.[filed.IndexFieldName]) ||
              ''
              }</span>
                    </p>`;
          })
          .join('') ||
        '';
    } else {
      let defaultStr =
        config.IndexName == 'folder'
          ? `<div class="imgBox">
            <img src='${iconUri}' style="width: ${showStyle == 'thumbnail' ? '65px' : '80px'}" />
        </div>
        <p class="searchItem_filename_box" title="${data.RawData?.foldername || ''}">${setHighLightWord(data.RawData?.foldername) || ''}</p>`
          : `<div class="imgBox">
            <img src='/Thumbnails/default/${data.RawData.fileid
          }.jpg' object-fit='cover' onerror='this.src="${iconUri}";this.style.width="${showStyle == "thumbnail" ? "65px" : "80px"}"'/>
        </div>
        <p class="searchItem_filename_box ${config.Mark ? 'searchItem_filename_box_mark' : ''}" title="${data.RawData?.filename || ''
          }" ><img class="itemImg" src="${iconUri}" />${setHighLightWord(data.RawData?.filename) || ''}</p>`;
      if (config.Mark) {
        defaultStr += `<div class="searchItem_similary_box">
          <span style="color:#999">相似度：
            <span style="color: var(--search-color)">
              ${((data.RawData?.similary || 0) * 100).toFixed(2)}%
            </span>
          </span>
          <div class="similary_btn">
            <span class='iconContainer'>
            <svg width="16px" height="16px" fill="currentColor" aria-hidden="true" focusable="false" class="">
              <use xlink:href="#icon-ico-Searchforpictures"></use>
            </svg>
            </span>
          </div>
        </div>`;
      }
      htmlStr =
        configEvents.current?.onRenderItem?.({
          data,
          columnField: config.columnField,
          type: 'thumbnail',
          IndexName: config.IndexName,
          checked,
          config,
          setTag,
          dataList
        }) || defaultStr;
    }
    // item 为内置列项、 缩略图视图
    const Item = (
      <div
        className={`content${showStyle}Item ${checked ? 'checked' : ''} ${config.Mark ? 'markBox' : ''
          }`}
      >
        {$checkbox}
        <div
          className={`content${showStyle}Item-content`}
          dangerouslySetInnerHTML={{ __html: htmlStr }}
          onClick={(e) => {
            e.stopPropagation()
            //@ts-ignore
            // use第一级  svg第二级 div第三级
            if (
              data.RawData?.fileid !== undefined &&
              (e.target?.className?.includes?.('similary_btn') ||
                e.target?.parentNode?.className?.includes?.('similary_btn') ||
                e.target?.parentNode?.className?.includes?.('iconContainer') ||
                e.target?.parentNode?.parentNode?.className?.includes?.('similary_btn') ||
                e.target?.parentNode?.parentNode?.className?.includes?.('iconContainer')
              )

            ) {
              const IndexName = config.IndexCode === '_document_' ? '_document_' : config.IndexName;
              inbiz(config['controlId']).load({
                IndexName: [IndexName],
                documentType: config.IndexCode === '_document_' || config.IndexCode === 'file' ? 'file' : undefined,
                KeyWord: '',
                ImgMarkId: data.RawData.fileid,
              });
            } else if (e.target?.className?.includes?.('itemImg') ||
              e.target?.className?.includes?.('searchItem_filename_box') ||
              e.target?.parentNode?.className?.includes?.('searchItem_filename_box') ||
              e.target?.className?.includes?.('itemTitle')) {
              config.IndexName == 'folder' ? previewFolder() : previewFile()
            } else {
              onSelect?.(data, !checked)
            }
            emit?.('onClick', 'resultItem', { IndexName: config.IndexName, data, event: e });
          }}
        />
      </div>
    );

    // 视图类型为列项时用Item, 为自定义时用上传模板。自定义上传模板分为 列项模板,和缩略图, 当上传模板不存在时，采用内置视图
    return config.columnType === 'list'
      ? Item
      : view[showStyle === 'list' ? 'ListView' : 'ThumbnailView']?.({
        data,
        checkbox: $checkbox,
        icon: iconUri as string,
        checked,
        config,
        inbiz,
        KeyWord: params.KeyWord,
        SecondaryWord: params.SecondaryWord,
        setTag,
        emit,
        dataList,
        onSelect,
        getMessage,
        GlobalRegistry,
        version: 6
      }) || Item;
  }, [config, checked, onSelect, data, view, showStyle]) as ReactElement;
}

type IView = ReturnType<typeof useTemplate>[0];
function ContentBody({
  showStyle,
  dataSoure,
  config,
  view,
  selected,
  uniqueKey,
  onSelect,
  loading,
  designer,
  params,
  $params

}: {
  view: IView;
  showStyle: IConfigItem['config']['showStyle'];
  config: IConfigItem['config'];
  checkList?: string[];
  onSelect?: (node: ISearchData['RawList'][number], checked: boolean) => void;
  dataSoure?: ISearchData['RawList'];
  loading: boolean;
  selected: ISearchData['RawList'];
  uniqueKey: string;
  params: any,
  $params: any

}) {

  const { configEvents, emit, inbiz } = useContext(EventContext);
  const emptyDiv = useMemo(() => {
    return showStyle !== 'list'
      ? Array.from({ length: 20 }).map((_, index) => (
        <div className={`content${showStyle}Item emptydiv`} key={'emptydiv' + index} />
      ))
      : null;
  }, [showStyle]);
  const _key = useMemo(() => Math.random(), [dataSoure]);

  if (configEvents.current?.onRenderBody) {
    const RenderBody = configEvents.current?.onRenderBody;
    return (
      <div className="content-body">
        <RenderBody
          showStyle={showStyle}
          dataSoure={dataSoure}
          config={config}
          selected={selected}
          uniqueKey={uniqueKey}
          onSelect={onSelect}
          loading={loading}
          emit={emit}
          inbiz={inbiz}
        />
      </div>
    );
  }
  const dataList = useMemo(() => {
    return dataSoure?.map(item => {
      return item.RawData
    })
  }, [dataSoure])
  return (
    <div className={`content-body  ${config.sectionDisplayPosition === 'left' ? 'leftcontentmain' : ''} ${config.sectionDisplayPosition === 'right' ? 'rightcontentmain' : ''} `}>
      {!dataSoure?.length ? (
        !loading && (
          <Empty
            description={getMessage('SearchResultEngine.noData')}
            image={<InbizIcon type="icon-ic-zanwushuju" />}
          />
        )
      ) : (
        //@ts-ignore item-margin-right 缩略图模型下使用
        <div
          className={showStyle}
          style={{
            //@ts-ignore
            '--item-margin-right': '60px',
            '--item-width': '196px',
          }}
        >
          {dataSoure?.map((item, index) => {
            return (
              <ContentItem
                key={`${index}_${item?.RawData?.[config.columnField?.[0]?.IndexFieldName]}_${item?.RawData?.[config.columnField?.[1]?.IndexFieldName]
                  }_${_key}`}
                data={item}
                checked={
                  !!selected.find(
                    (select) => select.RawData?.[uniqueKey] === item.RawData?.[uniqueKey],
                  )
                }
                onSelect={onSelect}
                view={view}
                config={config}
                showStyle={showStyle}
                params={params}
                $params={$params}
                dataList={dataList}
              />
            );
          })}
          {emptyDiv}
        </div>
      )}
      {!designer && loading && (
        <div className="spinBox">
          <Spin size="large" />{' '}
        </div>
      )}
    </div>
  );
}
export default ContentBody;
